///////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
#ifndef __GPUPROGRAM_H__
#define __GPUPROGRAM_H__

#include <Config.h>
#include <string>
#include <map>
#include <set>

class	File;
class	TiXmlElement;

//-----------------------------------------------------------------------------

/**
 * Clasa abstracta pura ce reprezinta un program
 * pentru GPU
 */
class GPUProgram
{
public:
	/**
	*	Constructor
	*/
						GPUProgram();

	/**
	* Pentru polimorfism
	*/
	virtual				~GPUProgram() {}

	/**
	* Incarca programul din fisier; primeste ca intrare
	* fisierele sursa pt. vertex si fragment shader
	*/
	virtual bool		Load(File* sourceVS, File* sourceFS, const char *vertexFunc = "", const char *fragFunc = "", const char *argsV = "", const char *argsF = "") = 0;
	
	/**
	* Compileaza programul
	*/
	virtual bool		Compile() = 0;

	/**
	* Link-editeaza programul
	*/
	virtual bool		Link() = 0;
	
	/**
	* Valideaza programul
	*/
	virtual bool		Validate() = 0;

	/**
	*	Preload all the uniforms/attribs for easier acces per frame
	*/
	virtual void		LoadParameters() = 0;

	/**
	*	Has parameter
	*/
	virtual bool		HasParameter(const char* paramName) = 0;
	
	/**
	* Stabileste valoarea pentru un parametru
	* al programului de tip intreg(sau sampler, bool)
	*/
	virtual void		SetParameter1i(const char* paramName, int value) = 0;
	virtual void		SetParameter2i(const char* paramName, int* value) = 0;
	virtual void		SetParameter3i(const char* paramName, int* value) = 0;
	virtual void		SetParameter4i(const char* paramName, int* value) = 0;
	
	/**
	* Stabileste valoarea pentru un parametru
	* al programului de tip float
	*/
	virtual void		SetParameter1f(const char* paramName, float value) = 0;
	virtual void		SetParameter2f(const char* paramName, float* value) = 0;
	virtual void		SetParameter3f(const char* paramName, float* value) = 0;
	virtual void		SetParameter4f(const char* paramName, float* value) = 0;

	/**
	* Stabileste valoarea pentru un parametru
	* al programului de tip sampler2D
	*/
	virtual void		SetParameterTexture(const char* paramName, GLuint textureHandle, GLuint textureUnit) = 0;
	virtual void		SetParameterMatrixf(const char* paramName, GLfloat *mat) = 0;

	/**
	* Activeaza/dezactiveaza folosirea programului
	*/
	virtual void		Use(bool use = true) = 0;
	
	/**
	* Sterge programul si codul sau obiect
	*/
	virtual void		Delete() = 0;

	/**
	*	Shader filename
	*/
	virtual void		SetFilename(std::string filename);
	virtual bool		IsThisShader(std::string filename);
	virtual std::string	GetFilename();

	/**
	*	Read shader params from input XML
	*/
	virtual void		ParseElement(TiXmlElement* elem);

	/*
	*	Get the name of the shader attribute/parameter for a texture unit
	*/
	std::string			GetParamNameForTextureUnit(u8 unit);

	/**
	*	Acount for textures
	*/
	void				BeginTextureBind();
	void				EndTextureBind();

protected:

	/**
	* Pentru a evita activarea repetata a programului
	*/
	bool m_inUse;

private:

	std::string			m_filename;

	std::map<u8, std::string>	m_textureMap;
	std::map<u8, std::string>	m_textureMapSearch;

	std::set<u8>		m_textureBind;
};

#endif // __GPUPROGRAM_H__
//-----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////

